package com.ylsdxy.auth.config;

import com.ylsdxy.auth.entity.User;
import com.ylsdxy.auth.mapper.UserMapper;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;


@Configuration
public class TokenConfiguration {
    // 秘钥
    private static String SIGNING_KEY="www.woniuxy.com";
    @Resource
    private UserMapper userMapper;

    // token转换器
    @Bean
    public JwtAccessTokenConverter accessTokenConverter() {
        JwtAccessTokenConverter jwtAccessTokenConverter =  new JwtAccessTokenConverter(){
            @Override
            public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
                final Map<String, Object> additionalInfo = new HashMap<>();
                String username = authentication.getName();
                //认证时使用authentication.getUserAuthentication().getPrincipal();可以正常转换为user对象
                //但刷新时会报String无法转换异常,是因为刷新时oauth2不会再去认证获取用户信息所以之前的代码只能获取一个字符串表示用户名
                //所以这里再次获取一遍UserDetails
                User user = (User) userMapper.findByAccount(username);

                // 将用户id放到token中
                additionalInfo.put("uid", user.getId());

                ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);
                return super.enhance(accessToken, authentication);
            }
        };
        jwtAccessTokenConverter.setSigningKey(SIGNING_KEY);
        return jwtAccessTokenConverter;
    }

    @Resource
    private DataSource dataSource;
    // 令牌存储策略:jwt方式
    // JdbcTokenStore：数据库存储token
    @Bean
    public TokenStore tokenStore(){
       //return new JwtTokenStore(accessTokenConverter());
        return new JdbcTokenStore(dataSource);
    }
}